﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace MicroMVVM
{
    internal sealed class AppDomain
    {
        /// <summary>
        /// Represents the current application domain.
        /// </summary>
        public static AppDomain CurrentDomain { get; private set; }

        /// <summary>
        /// The entry point for the AppDomain implementation.
        /// </summary>
        static AppDomain()
        {
            CurrentDomain = new AppDomain();
        }

        /// <summary>
        /// Public accessor method to load assemblies.
        /// </summary>
        /// <returns></returns>
        public Assembly[] LoadAssemblies()
        {
            return GetAssemblies().Result.ToArray();
        }

        /// <summary>
        /// Loads the assemblies from the installed location.
        /// </summary>
        /// <returns>Assemblies</returns>
        private async Task<IEnumerable<Assembly>> GetAssemblies()
        {
            System.Diagnostics.Debug.WriteLine("Fetching assemblies process started.");

            var installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;

            var assemblies = new List<Assembly>();

            foreach (var storageFile in await installedLocation.GetFilesAsync())
            {
                try
                {
                    if (storageFile.FileType != ".dll" && storageFile.FileType != ".exe") continue;

                    var name = Path.GetFileNameWithoutExtension(storageFile.Name);

                    System.Diagnostics.Debug.WriteLine(string.Format("Found assembly {0}.", name));

                    var assemblyName = new AssemblyName {Name = name};

                    var assembly = Assembly.Load(assemblyName);

                    assemblies.Add(assembly);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(string.Format("Failed loading assembly {0}.", ex.Message));
                }
            }

            return assemblies;
        }
    }
}